package com.simon.cdc.database;

import com.alibaba.druid.pool.DruidDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * Druid连接池封装管理
 */
public class DatabaseConnectionPool {
    private final DruidDataSource dataSource;

    public DatabaseConnectionPool(DatabaseConnectionConfig config) {
        this.dataSource = createDruidDataSource(config);
    }

    /**
     * 获取数据库连接
     *
     * 此方法旨在提供一个数据库连接，使用数据源对象来建立连接
     * 通过封装获取连接的逻辑，使得其他方法可以通过调用本方法来获取数据库连接
     *
     * @return Connection 数据库连接对象
     * @throws SQLException 如果获取连接时发生错误，抛出此异常
     */
    public Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    /**
     * Closes the data source if it is not null.
     *
     * This method is primarily used to release resources, ensuring that the data source is properly closed when no longer needed.
     * It is a fundamental method for managing resources in the class, helping to prevent resource leaks.
     *
     * @throws SQLException If an SQL error occurs while closing the data source.
     */
    public void close() throws SQLException {
        if (dataSource != null) {
            dataSource.close();
        }
    }

    /**
     * 创建Druid数据源实例
     *
     * @param config 数据库连接配置对象，包含数据库连接所需的信息
     * @return 返回一个配置好的DruidDataSource实例
     */
    private DruidDataSource createDruidDataSource(DatabaseConnectionConfig config) {
        // 创建DruidDataSource实例
        DruidDataSource ds = new DruidDataSource();

        // 设置数据库连接URL
        ds.setUrl(config.getJdbcUrl());
        // 设置数据库用户名
        ds.setUsername(config.getUsername());
        // 设置数据库密码
        ds.setPassword(config.getPassword());
        // 设置连接池的初始大小
        ds.setInitialSize(config.getInitialPoolSize());
        // 设置连接池的最大活跃数
        ds.setMaxActive(config.getMaxPoolSize());
        // 设置用于验证连接的查询语句
        ds.setValidationQuery("SELECT 1");
        // 设置是否在空闲时进行验证
        ds.setTestWhileIdle(true);
        // 设置空闲连接检测的时间间隔
        ds.setTimeBetweenEvictionRunsMillis(60000);

        // 返回配置好的DruidDataSource实例
        return ds;
    }
}